package com.cashoutgaming.client.common;

import java.io.Serializable;
import java.util.Date;
import com.cashoutgaming.shared.user.UserLightDTO;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Timer;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.HandlerRegistration;
import com.gwtplatform.mvp.client.proxy.PlaceRequest;
import com.sencha.gxt.widget.core.client.Dialog;
import com.sencha.gxt.widget.core.client.box.AlertMessageBox;
import com.sencha.gxt.widget.core.client.event.HideEvent;
import com.sencha.gxt.widget.core.client.event.HideEvent.HideHandler;

public class SessionManager implements Serializable {

	private static final long serialVersionUID = -531224281306240068L;
	PlaceRequest lastPlaceRequest;
	private UserLightDTO user;

	// Real Time Intervals
	public final static int ONE_SECOND = 1000;
	public final static int SECONDS = 60;

	public final static int ONE_MINUTE = ONE_SECOND * 60;
	public final static int MINUTES = 60;

	public final static int ONE_HOUR = ONE_MINUTE * 60;
	public final static int HOURS = 24;

	public final static int ONE_DAY = ONE_HOUR * 24;

	// Timers
	private Timer sessionHeartbeatTimer;
	private Timer sessionWarningTimer;
	private Timer sessionLogoffTimer;

	// Session Keep Alive Iteration Interval
	private final static int HEARTBEAT_INTERVAL = ONE_MINUTE * 5;
	private final static int WARNING_INTERVAL = ONE_MINUTE * 60;
	private final static int LOGOFF_INTERVAL = ONE_MINUTE * 5;

	private AlertMessageBox warningBox;
	private HandlerRegistration sessionActivityHandler;

	@Inject
	public SessionManager() {

	}

	public void clearSession() {
		user = null;
		Cookies.removeCookie("user_credentials");
		Cookies.removeCookie("lpr");
		Cookies.removeCookie("cog_creds");
		if (sessionLogoffTimer != null) {
			sessionLogoffTimer.cancel();
		}
		if (sessionWarningTimer != null) {
			sessionWarningTimer.cancel();
		}
		if (warningBox != null) {
			if (warningBox.isRendered()) {
				warningBox.hide();
			}
			warningBox = null;
		}
		if (sessionActivityHandler != null) {
			sessionActivityHandler.removeHandler();
			sessionActivityHandler = null;
		}
	}

	public boolean isDevelopmentMode() {
		return !GWT.isProdMode() && GWT.isClient();
	}

	public UserLightDTO getUser() {
		return user;
	}

	public void setUser(UserLightDTO user) {
		this.user = user;
	}

	// Time Management Below
	public void sessionStartup() {
		Date date = new Date();
		GWT.log(date.toString() + ": Session Manager started.");
		activateSessionHeartbeat();
		activateWarningTimer();

		if (sessionLogoffTimer != null) {
			sessionLogoffTimer.cancel();
		}
		if (warningBox != null) {
			warningBox.hide();
			warningBox = null;
		}
	}

	public void activateSessionHeartbeat() {
		if (getUser() != null) {
			if (sessionHeartbeatTimer == null) {
				sessionHeartbeatTimer = new Timer() {

					@Override
					public void run() {
						performKeepAliveCall();
					}
				};
			}
			else {
				sessionHeartbeatTimer.cancel();
			}
			sessionHeartbeatTimer.schedule(HEARTBEAT_INTERVAL);
			Date date = new Date();
			GWT.log(date.toString() + ": Heartbeat started.");
		}
	}

	public void performKeepAliveCall() {
		if (getUser() != null) {
			// TODO call keep alive
		}
	}

	public void activityOccurance() {
		Date date = new Date();
		GWT.log(date.toString() + ": Activity Occurred, warning timer resetting.");
		if (sessionWarningTimer != null) {
			sessionWarningTimer.cancel();
		}
		if (sessionLogoffTimer != null) {
			sessionLogoffTimer.cancel();
		}
		if (warningBox != null) {
			warningBox.hide();
			warningBox = null;
		}
		activateWarningTimer();
	}

	public void activateWarningTimer() {
		if (getUser() != null) {
			if (sessionWarningTimer == null) {
				sessionWarningTimer = new Timer() {

					@Override
					public void run() {
						showWarning();
					}
				};
			}
			else {
				sessionWarningTimer.cancel();
			}
			Date date = new Date();
			GWT.log(date.toString() + ": Warning timer active.");
			sessionWarningTimer.schedule(WARNING_INTERVAL);
		}
	}

	public void activateLogoffTimer() {
		if (getUser() != null) {
			if (sessionLogoffTimer == null) {
				sessionLogoffTimer = new Timer() {

					@Override
					public void run() {
						terminateSession();
					}
				};
			}
			else {
				sessionLogoffTimer.cancel();
			}
			Date date = new Date();
			GWT.log(date.toString() + ": Logoff timer active.");
			sessionLogoffTimer.schedule(LOGOFF_INTERVAL);
		}
	}

	public void showWarning() {
		warningBox = new AlertMessageBox("Inactive Warning", "You have been inactive for 60 minutes.\nClick OK to continue working.");
		warningBox.addHideHandler(new HideHandler() {

			@Override
			public void onHide(HideEvent event) {
				Dialog btn = (Dialog) event.getSource();
				// if (btn.getHideButton() != null) {
				// String btnClicked = btn.getHideButton().getText();
				// if (btnClicked.equalsIgnoreCase("ok")) {
				// activityOccurance();
				// }
				// }
			}
		});
		activateLogoffTimer();
		warningBox.show();
	}

	public void terminateSession() {
		clearSession();
	}
}
